﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GAIA_Logica
{
    public class Calculos
    {

        public static double getVolumenTotal(double pDAP,double pHC,int pnumFormula){

            double result = -1;

            switch (pnumFormula)
            {
                case 1:
                    result = (0.000248 * (Math.Pow(pDAP, 1.81847))) * (Math.Pow(pHC, 0.64862));
                    break;
                case 2:
                    result = (0.000171 * (Math.Pow(pDAP, 1.95698))) * (Math.Pow(pHC, 0.63653));
                    break;
                case 3:
                    result = (0.000166 * (Math.Pow(pDAP, 1.82571))) * (Math.Pow(pHC, 0.95281));
                    break;
                case 4:
                    var log1 = getLog(pDAP);
                    var log2 = getLog(pHC);

                    result = (2.03986 * log1) + ((0.779 * log2) - 4.07682);
                    result = Math.Pow(10, result);
                    break;

            }

            //Redondear a dos decimales
            result = Math.Round(result, 6);

            return result;
        }


    private static double getLog(double valor){
	    double log1 = valor;
	    double base1 =10;
	    double dn=1;
	    dn=Math.Log(base1);
	    double ans=Math.Log(log1)/dn;
	    return ans;
    }


    public static double getAreaBasal(double pDAP, double pHC)
        {
            //pDap en centimetros
            //pHc en metros
            double result = -1;

            //El pDap viene en centimetros por ello se convierte a metros
            result = ((Math.Pow((pDAP / 2),2))*Math.PI)/10000;

            //Redondear a dos decimales
            result = Math.Round(result, 6);

            return result;
        }


        //Retorna los calculos respectivos
        public static Dictionary<String, double> getCalculos(double pDAP, double pHC, int pnumFormula)
        {
            //Lista retorno
            Dictionary<String, double> valores = new Dictionary<String, double>();

            valores.Add("area",getAreaBasal(pDAP,pHC));
            valores.Add("volumen", getVolumenTotal(pDAP, pHC, pnumFormula));

            return valores;
        }

        //Obtiene crmt05N apartir de lambert norte ye 
        public static double getCrmt05N(double nl, double el)
        {
            double result = 0.0;

            double fe = 500000.0;
            double e = (el - fe) * 0.00001;

            if (nl > 0 && el > 0)
            {
                double fn = 271820.52;
                double n = (nl - fn) * 0.00001;
                double a00 = 1156874.11;
                double a10 = 99964.18;
                double a01 = -105.22;
                double a20 = -0.01;
                double a11 = -8.97;
                double a30 = -4.15;
                double a21 = 0.03;
                double a12 = 12.37;
                double a03 = 0;
                double b00 = 463736.66;
                double b10 = 105.19;
                double b01 = 99964.19;
                double b20 = 4.49;
                double b02 = -4.49;
                double b21 = -12.39;
                double b12 = 0.03;
                double b03 = 4.12;

                double n90 = a00 + a10 * n + a01 * e + a20 * n * n + a11 * n * e + a30 * n * n * n + a21 * n * n * e + a12 * n * e * e + a03 * e * e * e;
                double e90 = b00 + b10 * n + b01 * e + b20 * n * n + b02 * e * e + b21 * n * n * e + b12 * n * e * e + b03 * e * e * e;

                if (!((n90 < 1056672 || n90 > 1237077) || (e90 < 283690 || e90 > 663760)))
                {
                    double a0 = -7.75237044;
                    double b0 = -3.525688428;
                    double a1 = 1.00000086635;
                    double b1 = -0.00000000018;
                    double n98 = a0 + a1 * n90 - b1 * e90;
                    double e98 = b0 + a1 * e90 + b1 * n90;
                    a0 = -0.179913184;
                    b0 = -149.644487588;
                    a1 = 1.00030018487;
                    b1 = -0.00000034731;
                    result = a0 + a1 * n98 - b1 * e98;

                }

            }

            result = getMinDec(result);
            return result;
        }

        public static double getCrmt05E(double nl, double el)
        {
            double result = 0.0;

            double fe = 500000.0;
            double e = (el - fe) * 0.00001;


            if (nl > 0 && el > 0)
            {
                double fn = 271820.52;
                double n = (nl - fn) * 0.00001;
                double a00 = 1156874.11;
                double a10 = 99964.18;
                double a01 = -105.22;
                double a20 = -0.01;
                double a11 = -8.97;
                double a30 = -4.15;
                double a21 = 0.03;
                double a12 = 12.37;
                double a03 = 0;
                double b00 = 463736.66;
                double b10 = 105.19;
                double b01 = 99964.19;
                double b20 = 4.49;
                double b02 = -4.49;
                double b21 = -12.39;
                double b12 = 0.03;
                double b03 = 4.12;

                double n90 = a00 + a10 * n + a01 * e + a20 * n * n + a11 * n * e + a30 * n * n * n + a21 * n * n * e + a12 * n * e * e + a03 * e * e * e;
                double e90 = b00 + b10 * n + b01 * e + b20 * n * n + b02 * e * e + b21 * n * n * e + b12 * n * e * e + b03 * e * e * e;

                if (!((n90 < 1056672 || n90 > 1237077) || (e90 < 283690 || e90 > 663760)))
                {
                    double a0 = -7.75237044;
                    double b0 = -3.525688428;
                    double a1 = 1.00000086635;
                    double b1 = -0.00000000018;
                    double n98 = a0 + a1 * n90 - b1 * e90;
                    double e98 = b0 + a1 * e90 + b1 * n90;
                    a0 = -0.179913184;
                    b0 = -149.644487588;
                    a1 = 1.00030018487;
                    b1 = -0.00000034731;
                    result = b0 + a1 * e98 + b1 * n98;

                }

            }

            result = getMinDec(result);
            return result;
        }

        public static double getMinDec(double value)
        {
            value = Math.Truncate(value * 1000) / 1000;
            //double result = Math.Round(value, 2, MidpointRounding.AwayFromZero);
            return value;
        }
    }
}
